bundle: extract DeploymentLock interface + workspace filesystem impl#5314
Draft
shreyas-goenka wants to merge 7 commits into
Draft
bundle: extract DeploymentLock interface + workspace filesystem impl#5314shreyas-goenka wants to merge 7 commits into
shreyas-goenka wants to merge 7 commits into
Conversation
Pure code-movement refactor. Wraps the existing workspace-filesystem lock
behavior behind a DeploymentLock interface so a follow-up PR can introduce
an alternative metadata-service-backed lock implementation without
touching deploy/destroy/bind callers again.
What changed:
- New bundle/deploy/lock/lock.go: DeploymentLock interface, Goal enum
(moved from release.go), DeploymentStatus enum, and a
NewDeploymentLock factory that unconditionally returns the workspace
filesystem implementation.
- New bundle/deploy/lock/workspace_filesystem.go: workspaceFilesystemLock
struct that implements DeploymentLock. Preserves the historical
behavior of the deleted acquire.go / release.go mutators: lock-disabled
short-circuit, locker.CreateLocker initialization, the
permissions.ReportPossiblePermissionDenied branch on fs.ErrPermission
/ fs.ErrNotExist, and the destroy-mode locker.AllowLockFileNotExist
unlock quirk.
- Deleted bundle/deploy/lock/acquire.go and bundle/deploy/lock/release.go.
- Updated bundle/phases/{deploy,destroy,bind}.go to construct the lock
once via NewDeploymentLock and call Acquire / Release directly instead
of through bundle.ApplyContext. The deferred Release now reports
DeploymentSuccess / DeploymentFailure based on logdiag.HasError so a
future DMS-backed implementation can record the outcome.
Behavior is preserved end-to-end: lock-related acceptance goldens
(pipelines/{deploy,destroy}/force-lock, bundle/help/bundle-{deploy,
destroy}) all pass unchanged.
Collaborator
|
Commit: 6cad232 |
This was referenced May 26, 2026
…dle.Bundle Pre-refactor the locker was stashed on b.Locker so the two mutators (acquire then release) could share it via the Bundle. After PR #5314 both lifecycle methods live on a single struct, so the cross-method state-passing through bundle.Bundle is redundant — grep finds zero external consumers of b.Locker. Move the *locker.Locker to a field on workspaceFilesystemLock and delete the now-unused Locker field on bundle.Bundle. Co-authored-by: Isaac
The struct now holds only the primitives + workspace client + a permission-error callback it needs. The bundle-aware wiring lives in NewDeploymentLock, which captures everything from the *bundle.Bundle at construction time. Why: keeps the type-level dependency surface narrow (the impl no longer imports bundle or bundle/permissions), removes a class of accidental coupling that would make alternative lock implementations awkward, and forecloses the possibility of a future bundle <-> lock import cycle. NewDeploymentLock now takes ctx so it can call b.WorkspaceClient(ctx) at construction; the three callers in bundle/phases are updated in one line each. Co-authored-by: Isaac
The lock and workspace_filesystem files live in the same package, so the package-level import of bundle/permissions exists regardless of whether the struct hides the call behind a function value. The callback only added a layer of indirection; switch to a direct permissions.ReportPossiblePermissionDenied call and keep a narrow b field purely for that error path. Co-authored-by: Isaac
The error is returned to the caller; logging it here just produces a duplicate line in the user-facing output. Drop the log; preserve the permission-denied branch and the bare return. Co-authored-by: Isaac
…or semantics) The original release.go mutator returned diag.FromErr on unlock failure, which surfaced as an error diagnostic to the user. The defer pattern introduced in #5314 dropped it to log.Warnf — a silent demotion that would hide a stuck lock from the user (who normally has to recover with --force-lock). Switch the defer to logdiag.LogError so the unlock failure shows up as a proper diagnostic, matching the pre-refactor behavior. The deploy/destroy/ bind/unbind phases all share the same fix. Co-authored-by: Isaac
shreyas-goenka
commented
May 28, 2026
|
|
||
| defer func() { | ||
| bundle.ApplyContext(ctx, b, lock.Release(lock.GoalBind)) | ||
| status := lock.DeploymentSuccess |
Contributor
Author
There was a problem hiding this comment.
status is not used for now - but will be used with deployment metadata service.
…lesystemLock ReportPossiblePermissionDenied has a second caller (bundle/deploy/files/ upload.go) and walks bundle.Config.RunAs / Permissions / Resources via analyzeBundlePermissions, so the lock can't simply inline it or call a simplified variant. But the struct doesn't need to pin a *bundle.Bundle field — the bundle-aware wiring can live in a callback closure that NewDeploymentLock builds at construction time. After this commit workspaceFilesystemLock holds only primitives, a workspace client, and the callback; no bundle types appear in its field list. Co-authored-by: Isaac
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Pure code-movement refactor. Wraps the existing workspace-filesystem lock behind a
DeploymentLockinterface so a follow-up PR can ship a metadata-service-backed implementation without touchingdeploy/destroy/bindcallers again.What changed
bundle/deploy/lock/lock.go—DeploymentLockinterface,Goalenum (moved fromrelease.go),DeploymentStatusenum, and aNewDeploymentLockfactory that unconditionally returns the workspace filesystem implementation.bundle/deploy/lock/workspace_filesystem.go—workspaceFilesystemLockimplementsDeploymentLock. Preserves the historical behavior of the deleted mutators: lock-disabled short-circuit,locker.CreateLockerinitialization, thepermissions.ReportPossiblePermissionDeniedbranch onfs.ErrPermission/fs.ErrNotExist, and the destroy-modelocker.AllowLockFileNotExistunlock quirk.bundle/deploy/lock/acquire.goandbundle/deploy/lock/release.go.bundle/phases/{deploy,destroy,bind}.goto construct the lock once viaNewDeploymentLockand callAcquire/Releasedirectly instead of viabundle.ApplyContext. The deferredReleasenow passesDeploymentSuccess/DeploymentFailurebased onlogdiag.HasError(ctx)so a future DMS-backed implementation can record the outcome.Test plan
go build ./...cleango vet ./bundle/deploy/lock/... ./bundle/phases/...cleango test ./bundle/... ./cmd/...green-update:pipelines/{deploy,destroy}/force-lock,bundle/help/bundle-{deploy,deployment,deployment-migrate,destroy}./task lintclean (0 issuesx3)databricks/cliPre-existing acceptance failures on
origin/main(bundle/deployment/bind/job/...,bundle/templates/pydabs/check-consistency,bundle/resources/jobs/update*, etc.) reproduce identically on this branch and are unrelated to this refactor.